package com.shiro.demo3.utils;

import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.util.Date;
public class JwtUtils {
    // 设置过期时间
    private static final long EXPIRE = 1000 * 60 * 60 *24;
    // 秘钥
    private static final String APP_SECRET = "451f890350e51c0a45ada5ea9c943637";

    /**
     * 生成token
     * @param id
     * @param username
     * @return
     */
    public static String getJwtToken(String id,String username){
        String jwtToken = Jwts.builder()
                // 设置头部,固定的,不用修改
                .setHeaderParam("typ","JWT")
                .setHeaderParam("alg","HS256")
                // 设置过期时间
                .setSubject("baidu-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                // 设置主题部分,存储用户信息
                .claim("id",id)
                .claim("username",username)
                // 设置编码方式
                .signWith(SignatureAlgorithm.HS256,APP_SECRET)
                .compact();
        return jwtToken;
    }
    /**
     * 判断token是否存在与有效
     */
    public static boolean checkToken(String jwtToken){
        if (!StringUtils.hasText(jwtToken)) {
            return false;
        }
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 判断token是否存在与有效
     */
    public static boolean checkToken(HttpServletRequest request){
        String jwtToken = request.getHeader("token");
        if (!StringUtils.hasText(jwtToken)) {
            return false;
        }
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 根据token获取用户id
     */
    public static String getUserIdByJwtToken(String jwtToken){
        if (!StringUtils.hasText(jwtToken)) {
            return "";
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String) claims.get("id");
    }
    /**
     * 根据token获取用户id
     */
    public static String getUserIdByJwtToken(HttpServletRequest request){
        String jwtToken = request.getHeader("token");
        if (!StringUtils.hasText(jwtToken)) {
            return "";
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String) claims.get("id");
    }
    /**
     * 根据token获取用户username
     */
    public static String getUsernameByJwtToken(String jwtToken){
        if (!StringUtils.hasText(jwtToken)) {
            return "";
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String) claims.get("username");
    }
    /**
     * 根据token获取用户username
     */
    public static String getUsernameByJwtToken(HttpServletRequest request){
        String jwtToken = request.getHeader("token");
        if (!StringUtils.hasText(jwtToken)) {
            return "";
        }
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String) claims.get("username");
    }
    /**
     * 刷新令牌
     * @param token 原令牌
     * @return 新令牌
     */
    public static String refreshToken(String token) {
        String refreshedToken;
        try {
            Claims claims = getClaimsFromToken(token);
            long instantNow = Instant.now().toEpochMilli();
            refreshedToken = Jwts.builder().setClaims(claims).setIssuedAt(new Date(instantNow))
                    .setExpiration(new Date(instantNow + EXPIRE))
                    .signWith(SignatureAlgorithm.HS256,APP_SECRET).compact();
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }
    /**
     * 移除令牌
     * @param token 原令牌
     * @return 移除的令牌
     */
    public static String removeToken(String token) {
        String refreshedToken;
        try {
            Claims claims = getClaimsFromToken(token);
            long instantNow = Instant.now().toEpochMilli();
            refreshedToken = Jwts.builder().setClaims(claims).setIssuedAt(new Date(instantNow))
                    .setExpiration(new Date(instantNow))    // 设置当前时间为过期时间,就相当于移除了
                    .signWith(SignatureAlgorithm.HS256,APP_SECRET).compact();
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }
    /**
     * 解析JWT
     */
    public static Claims getClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token).getBody();
    }
}
